package com.fedoom.frontend.controllers;

import com.fedoom.frontend.models.*;
import com.fedoom.frontend.views.*;
import java.awt.Container;
import java.awt.event.*;
import java.util.*;

public class EngineController {
	/**
	 * Static fields should be used in any case where a dialog view is referenced.
	 * Is coded this way to ensure that setname method of each view, uses same name as 
	 * this enginecontroller does for referencing that view.
	 */
	public static final String single	="single", 
								mode 	="mode",
								av		="av",
								help	="help",
								welcome	="welcome";
	//Models, Views
	private StringBuilderModel sbm;
	private InfoView infoView;
	private ArgCollection ac;
	CommandLineFileLoader clfl;
	LinkedList<String> commandlist;
	
	/**
	 * replaces the direct references to each individual view.
	 */
	private HashMap<String, ModalView> views = new HashMap<String, ModalView>();
	
	
	//constructor
	public EngineController(StringBuilderModel sbm, InfoView infoView){

		//create models, views
		this.sbm = sbm;
		this.infoView = infoView;
		this.ac = new ArgCollection();
		
		//connect listeners to views
		infoView.addLaunchListener(new LaunchListener());
		loadViews();
		
		ViewListener vl = new ViewListener();
		infoView.addSingleListener(vl);
		infoView.addModeListener(vl);
		infoView.addAVListener(vl);
		infoView.addHelpListener(vl);
		
		infoView.addCloseListener(new CloseListener());
		
		setupFirstRunOrRegularRun();
		
		
	}

	/**
	 * Reads the config file the launcher creates (i.e. the serializable one).
	 * 
	 * NOTE: firstRun() seems like it should go here, but it doesn't work
	 * correctly if ran here.
	 */
	private void setupFirstRunOrRegularRun() {
		if (ac.isConfigFileExist()){
			ac.readConfig();
		}
		else  {
			firstRun();
		}
	}
	
	/**
	 * This method handles displaying of an info screen & the game mode screen, 
	 * if this is the first time the Launcher is being executed (the launcher config file is empty)
	 */
	private void firstRun()
	{
		ModalView mv = new WelcomeView(infoView);
		mv.setVisible(true);
		mv.dispose();//disposes welcome screen
		
		//gets game mode/config screen
		mv = views.get(EngineController.mode);
		mv.setVisible(true);//displayes game mode config screen
	}
	
	/**
	 * Returns the arg collection so FeDoom can check for empty file
	 * @return ArgCollection
	 */
	public ArgCollection getArgCollection()
	{
		return ac;
	}
	/**
	 * method used to:
	 *  create all of the dialog views
	 *  add views to the EngineControl hashmap
	 *  add listeners for each OK button on those views
	 *  update those views with data from ArgCollection
	 */
	private void loadViews() 
	{
		createViews();
		setupViews(new OKListener());

	}
	
	private void createViews()
	{
		views.put(EngineController.single, new SingleView());
		views.put(EngineController.mode, new ModeView());
		views.put(EngineController.av, new AVView());
		views.put(EngineController.help, new ModalView());
	}
	
	private void setupViews(ActionListener okl)
	{			
		Collection<ModalView> c=views.values();
		Iterator<ModalView> i = c.iterator();
		while (i.hasNext())
		{
			ModalView mv = i.next();
			mv.addOKListener(okl);
			ac.updateUI(mv);
		}
	}

	//Launch listener
	class LaunchListener implements ActionListener{
		public void actionPerformed(ActionEvent ae){
			ac.writeConfig();
			(new EngineController.CloseListener()).actionPerformed(ae);
			
			//Added JM - executes the built string
			ac.launch();
			
		}
	}
	
	//View  listener
	class ViewListener implements ActionListener{
		public void actionPerformed(ActionEvent ae){
	//code to find the JDialog that actually clicked the button.
			String button = ((Container)ae.getSource()).getName();
			ModalView mv = views.get(button);
			ac.updateUI(mv);
			mv.setVisible(true);
		}
	}	//inner listener
	class CloseListener implements ActionListener{
		public void actionPerformed(ActionEvent ae){
			Collection<ModalView> c=views.values();
			Iterator<ModalView> i = c.iterator();
			while (i.hasNext())
			{
				i.next().dispose();
			}
			infoView.dispose();
			
		}
	}
	public class OKListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			
	//code to find the JDialog that actually clicked the button.
			Container temp = ((Container)e.getSource()).getParent();
			ModalView mView;
			while(temp.getParent()!=null ){
				temp = temp.getParent();
//				System.out.println(temp.toString());
			}
			mView = ((ModalView)temp);
			ac.addValues(mView);
			ac.writeConfig();			// write command arg options to file
			mView.setVisible(false);
			//mView is whichever modal window just had its OK button clicked.
			//we can insert code here to handle transactions based on the type of window that was opened
			//The code on WHAT to do when OK is clicked can probably be the same for all modal windows
			//if for some reason it can't, we can use getName to make different windows perform different actions.
			
			//mView.getCompPanel can also be used to get textareas/text boxes that will need to be processed
		}

	}
}
